package com.yanboo.modules.security.config;

import com.yanboo.common.annotation.AnonymousAccess;
import com.yanboo.common.utils.enums.RequestMethodEnum;
import com.yanboo.modules.security.security.TokenUrlInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;

import java.util.*;

@Component
public class WebAppConfigurer implements WebMvcConfigurer {


    @Autowired
    @Lazy
    TokenUrlInterceptor tokenUrlInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 匹配所有接口，排除/base/test接口
        registry.addInterceptor(tokenUrlInterceptor).addPathPatterns("/**");
    }

    private Map<String, Set<String>> getGeneralUrl(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
        Map<String, Set<String>> generalUrls=new HashMap<>(8);
        Set<String> get = new HashSet<>();
        Set<String> post = new HashSet<>();
        Set<String> put = new HashSet<>();
        Set<String> patch = new HashSet<>();
        Set<String> delete = new HashSet<>();
        Set<String> all = new HashSet<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
            HandlerMethod handlerMethod = infoEntry.getValue();
            if (!handlerMethod.hasMethodAnnotation(AnonymousAccess.class)) {
                List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
                RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
                switch (Objects.requireNonNull(request)) {
                    case GET:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        get.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                    case POST:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        post.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                    case PUT:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        put.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                    case PATCH:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        patch.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                    case DELETE:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        delete.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                    default:
                        assert infoEntry.getKey().getPathPatternsCondition() != null;
                        all.addAll(infoEntry.getKey().getPathPatternsCondition().getPatterns().stream().map(PathPattern::getPatternString).toList());
                        break;
                }
            }
        }
        generalUrls.put(RequestMethodEnum.GET.getType(), get);
        generalUrls.put(RequestMethodEnum.POST.getType(), post);
        generalUrls.put(RequestMethodEnum.PUT.getType(), put);
        generalUrls.put(RequestMethodEnum.PATCH.getType(), patch);
        generalUrls.put(RequestMethodEnum.DELETE.getType(), delete);
        generalUrls.put(RequestMethodEnum.ALL.getType(), all);
        return generalUrls;
    }
}
